import MyAddressCascader from '@/components/MyAddressCascader';
import MyForm from '@/components/MyForm';
import MyOrgSelect from '@/components/MyOrgSelect';
import MyPageContainer from '@/components/MyPageContainer';
import MyScrollTable from '@/components/MyScrollTable';
import MyUpload from '@/components/MyUpload';
import useAuth from '@/hooks/useAuth';
import useDefaultColumn from '@/hooks/useDefaultColumn';
import usePageVariable from '@/hooks/usePageVariable';
import { AUTH_TYPE, dateConfig, MENU_CODES } from '@/options';
import { getList as getRoleList } from '@/services/system/role';
import { addItem, delItem, detailItem, getList, updateItem } from '@/services/system/user';
import { getOptionBtn } from '@/util/table';
import {
  convertValue,
  getDefaultSelectListProps,
  getSelectList,
  onBirthdayChange,
  onIdCardChange,
  transformValue,
} from '@/util/util';
import { getPattern, regExps } from '@/util/validate';
import { UserOutlined } from '@ant-design/icons';
import {
  ProFormDatePicker,
  ProFormDependency,
  ProFormDigit,
  ProFormRadio,
  ProFormSelect,
  ProFormText,
} from '@ant-design/pro-components';
import { Avatar } from 'antd';
import React from 'react';

type DataType = USER_TYPE.Info;

const TableList: React.FC = () => {
  const { insertAuth, updateAuth, detailAuth, delAuth } = useAuth(MENU_CODES.USER);
  const defaultColumn = useDefaultColumn();
  const {
    formModel,
    setFormModel,
    formType,
    actionRef,
    formRef,
    currentRow,
    finishMsg,
    columns,
    changeForm,
    getFormTitle,
    delMsgOpen,
    setDelMsgOpen,
  } = usePageVariable<DataType>([
    defaultColumn.index,
    defaultColumn.title,
    {
      title: '头像',
      dataIndex: 'avatar',
      hideInSearch: true,
      valueType: 'avatar',
      render: (_, record) => {
        return <Avatar src={record.avatar} size={48} icon={<UserOutlined />} />;
      },
    },
    {
      title: '登录名',
      dataIndex: 'loginName',
    },
    defaultColumn.org,
    defaultColumn.searchOrg,
    defaultColumn.role,
    defaultColumn.mobile,
    defaultColumn.createTime,
    defaultColumn.searchCreateTime,
    defaultColumn.updateTime,
    defaultColumn.searchUpdateTime,
    {
      title: '操作',
      valueType: 'option',
      render: (_, record) => [
        updateAuth && getOptionBtn(AUTH_TYPE.UPDATE, () => changeForm(record, '1')),
        detailAuth && getOptionBtn(AUTH_TYPE.DETAIL, () => changeForm(record, '2')),
        delAuth && getOptionBtn(AUTH_TYPE.DELETE, () => changeForm(record, '3')),
      ],
    },
  ]);

  const delCall = () =>
    finishMsg(async () => {
      const ret = await delItem(currentRow!.id);
      setDelMsgOpen(false);
      if (ret.success) actionRef.current?.reload();
    });

  const onFinish = async (value: DataType) => {
    if (formType === '2') {
      setFormModel(false);
      return;
    }
    await finishMsg(async () => {
      await (formType === '1' ? updateItem({ ...value, id: currentRow!.id }) : addItem(value));
      setFormModel(false);
      actionRef.current?.reload();
      formRef.current?.resetFields();
    });
  };

  return (
    <MyPageContainer modelOk={delCall} delMsgOpen={delMsgOpen} modelCancel={setDelMsgOpen}>
      <MyScrollTable<DataType, PageParams>
        actionRef={actionRef}
        request={getList}
        columns={columns}
        clickAdd={changeForm}
        isAdd={insertAuth}
        postData={(data: DataType[]) => {
          return data.map((c) => {
            if (typeof c.roleId === 'string') {
              c.roleId = c.roleId.split(',');
            }
            return c;
          });
        }}
      />
      <MyForm
        formRef={formRef}
        title={getFormTitle()}
        onFinish={onFinish}
        open={formModel}
        onOpenChange={setFormModel}
        readonly={formType === '2'}
        initialValues={{
          seq: 0,
        }}
        request={currentRow?.id ? () => detailItem(currentRow!.id) : undefined}
      >
        <ProFormText
          label="名称"
          name="title"
          fieldProps={{
            maxLength: 30,
            showCount: true,
          }}
          rules={[
            {
              required: true,
              message: '名称为必填项',
            },
          ]}
        />
        <ProFormText
          label="登录名"
          name="loginName"
          fieldProps={{
            maxLength: 30,
            showCount: true,
          }}
          rules={[
            {
              required: true,
              message: '登录名为必填项',
            },
            currentRow?.id === '1' ? {} : getPattern('loginName'),
          ]}
        />
        <ProFormText.Password
          label="密码"
          name="password"
          allowClear
          rules={[
            {
              required: formType === '0',
              message: '密码为必填项',
            },
            currentRow?.id === '1' ? {} : getPattern('password'),
          ]}
        />
        <MyOrgSelect
          fieldProps={{
            onChange: () => {
              formRef.current?.setFieldsValue({ roleId: undefined });
            },
          }}
        />
        <ProFormDependency name={['orgId']}>
          {({ orgId }) => {
            return (
              <ProFormSelect
                label="角色"
                name="roleId"
                mode="multiple"
                params={{ orgId }}
                request={(params) =>
                  getSelectList<ROLE_TYPE.Info>({
                    server: () => getRoleList(params),
                    label: 'title',
                    value: 'id',
                  })
                }
                convertValue={(value) => convertValue(value)}
                transform={(value) => transformValue(value)}
                rules={[
                  {
                    required: true,
                    message: '角色为必填项',
                  },
                ]}
              />
            );
          }}
        </ProFormDependency>

        <ProFormText
          label="身份证号"
          name="idCard"
          fieldProps={{
            maxLength: 18,
            showCount: true,
            onChange: (e) => {
              const idCard = e.target.value;
              if (idCard && regExps.idCard.test(idCard)) {
                const { birthday, age, sex } = onIdCardChange(idCard);
                formRef.current?.setFieldsValue({ birthday, age, sex });
              }
            },
          }}
          rules={[
            {
              required: true,
              message: '身份证号为必填项',
            },
            getPattern('idCard'),
          ]}
        />

        <ProFormRadio.Group
          label="性别"
          name="sex"
          rules={[
            {
              required: true,
              message: '性别为必填项',
            },
          ]}
          request={() => getSelectList(getDefaultSelectListProps('sex'))}
        />
        <ProFormDatePicker
          label="出生日期"
          name="birthday"
          rules={[
            {
              required: true,
              message: '出生日期为必填项',
            },
          ]}
          fieldProps={{
            minDate: dateConfig.minDate,
            maxDate: dateConfig.maxDate,
            onChange: (_, dateStr) => {
              if (dateStr)
                formRef.current?.setFieldsValue({
                  age: onBirthdayChange(dateStr as string),
                });
            },
          }}
        />
        <ProFormDigit label="年龄" name="age" min={1} readonly />

        <ProFormText label="邮箱" name="email" rules={[getPattern('email')]} />
        <ProFormText
          label="手机号码"
          name="mobile"
          rules={[
            {
              required: true,
              message: '手机号码为必填项',
            },
            getPattern('mobile'),
          ]}
        />
        <MyUpload max={1} fileType="image" />

        <MyAddressCascader name="address" />

        <ProFormDigit label="排序" name="seq" />
      </MyForm>
    </MyPageContainer>
  );
};

export default TableList;
